package com.monitor.util;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.monitor.model.MonitorConfig;
import com.monitor.model.ServerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 配置加载工具类
 * 负责从JSON文件加载服务器和监控配置
 */
public class ConfigLoader {
    private static final Logger logger = LoggerFactory.getLogger(ConfigLoader.class);
    private static final Gson gson = new Gson();
    
    // 默认路径配置
    private static final String DEFAULT_SERVERS_CONFIG_PATH = "servers.json";
    private static final String DEFAULT_MONITOR_CONFIG_PATH = "monitor.json";
    
    /**
     * 加载服务器配置
     * @return 服务器配置列表
     */
    public static List<ServerConfig> loadServers() {
        return loadServers(DEFAULT_SERVERS_CONFIG_PATH);
    }
    
    /**
     * 从指定路径加载服务器配置
     * @param configPath 配置文件路径
     * @return 服务器配置列表
     */
    public static List<ServerConfig> loadServers(String configPath) {
        try {
            // 尝试从当前目录加载配置文件
            File configFile = new File(configPath);
            InputStream inputStream;
            
            if (configFile.exists() && configFile.isFile()) {
                // 外部配置文件存在，使用外部配置
                logger.info("使用外部服务器配置文件: {}", configFile.getAbsolutePath());
                inputStream = new FileInputStream(configFile);
            } else {
                // 外部配置不存在，从classpath加载
                logger.info("外部服务器配置文件不存在，尝试从classpath加载");
                inputStream = ConfigLoader.class.getClassLoader().getResourceAsStream(configPath);
                if (inputStream == null) {
                    logger.error("服务器配置文件不存在: {}", configPath);
                    return new ArrayList<>();
                }
            }
            
            // 读取为JSON数组并转换为ServerConfig对象列表
            Type listType = new TypeToken<List<ServerConfig>>(){}.getType();
            List<ServerConfig> configs = gson.fromJson(
                new InputStreamReader(inputStream, StandardCharsets.UTF_8), 
                listType
            );
            
            inputStream.close();
            logger.info("成功加载{}个服务器配置", configs.size());
            return configs;
        } catch (IOException e) {
            logger.error("加载服务器配置失败: {}", e.getMessage());
            return new ArrayList<>();
        }
    }
    
    /**
     * 加载监控配置
     * @return 监控配置对象
     */
    public static MonitorConfig loadMonitorConfig() {
        return loadMonitorConfig(DEFAULT_MONITOR_CONFIG_PATH);
    }
    
    /**
     * 从指定路径加载监控配置
     * @param configPath 配置文件路径
     * @return 监控配置对象
     */
    public static MonitorConfig loadMonitorConfig(String configPath) {
        try {
            // 尝试从当前目录加载配置文件
            File configFile = new File(configPath);
            InputStream inputStream;
            
            if (configFile.exists() && configFile.isFile()) {
                // 外部配置文件存在，使用外部配置
                logger.info("使用外部监控配置文件: {}", configFile.getAbsolutePath());
                inputStream = new FileInputStream(configFile);
            } else {
                // 外部配置不存在，从classpath加载
                logger.info("外部监控配置文件不存在，尝试从classpath加载");
                inputStream = ConfigLoader.class.getClassLoader().getResourceAsStream(configPath);
                if (inputStream == null) {
                    logger.error("监控配置文件不存在: {}", configPath);
                    return null;
                }
            }
            
            // 读取为JSON对象并转换为MonitorConfig对象
            InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
            MonitorConfig config = gson.fromJson(reader, MonitorConfig.class);
            
            // 兼容处理：确保serviceList字段已正确读取
            // 如果JSON中使用的是monitoringServices字段，需要在这里进行转换
            if (config.getServiceList() == null) {
                // 尝试从旧字段读取
                try {
                    // 重新读取流
                    inputStream.close();
                    inputStream = configFile.exists() ? 
                        new FileInputStream(configFile) : 
                        ConfigLoader.class.getClassLoader().getResourceAsStream(configPath);
                        
                    reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
                    Map<String, Object> jsonMap = gson.fromJson(reader, Map.class);
                    
                    @SuppressWarnings("unchecked")
                    List<String> services = (List<String>) jsonMap.get("monitoringServices");
                    if (services != null) {
                        config.setServiceList(services);
                        logger.info("从旧字段'monitoringServices'读取服务列表");
                    }
                } catch (Exception e) {
                    logger.warn("无法从旧字段读取服务列表: {}", e.getMessage());
                }
            }
            
            inputStream.close();
            logger.info("成功加载监控配置");
            return config;
        } catch (IOException e) {
            logger.error("加载监控配置失败: {}", e.getMessage());
            return null;
        }
    }
} 